Skip to content

feat: add dimmedAlpha prop #151

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open

feat: add dimmedAlpha prop #151

wants to merge 9 commits into from

Conversation

camchis
Copy link

@camchis camchis commented Feb 26, 2025

  • Allow customisable dim alpha with dimmedAlpha prop - uses root view on iOS and a custom overlay view on Android to achieve this
  • Supports stacked sheets
  • Respects dimmed and dimmedIndex props

Requested in #78 and also find it useful for my own use case

Happy to add to docs if this looks good

Simulator.Screen.Recording.-.iPhone.16.Pro.Max.-.2025-02-26.at.21.31.59.mp4

Copy link

vercel bot commented Feb 26, 2025

@camchis is attempting to deploy a commit to the Jovanni's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copy link

codeclimate bot commented Feb 26, 2025

Code Climate has analyzed commit 6f6ffd8 and detected 2 issues on this pull request.

Here's the issue category breakdown:

Category Count
Duplication 2

View more on Code Climate.

Copy link

vercel bot commented Feb 26, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
react-native-true-sheet ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 26, 2025 10:49pm

@lodev09
Copy link
Owner

lodev09 commented Feb 26, 2025

Hey @camchis, thank you for this PR! I'll take a look tomorrow.

@lodev09
Copy link
Owner

lodev09 commented Mar 4, 2025

Hey @camchis, is it possible for you to add this feature on android as well?

@camchis
Copy link
Author

camchis commented Mar 5, 2025

Hey @camchis, is it possible for you to add this feature on android as well?

Will look into this today :)

@camchis camchis changed the title feat: add dimmedAlpha prop on iOS feat: add dimmedAlpha prop Mar 5, 2025
@camchis
Copy link
Author

camchis commented Mar 5, 2025

hey @lodev09, I've added Android support

@camchis
Copy link
Author

camchis commented Mar 19, 2025

@lodev09 do you have any thoughts on this PR? Would be great to get it released 🙏

@crux153
Copy link

crux153 commented Mar 27, 2025

@camchis It seems that the current code behaves oppositely on iOS and Android. If dimmedAlpha represents the alpha value, a lower number should make it more transparent, and a higher number should make it darker. This works as expected on Android, but on iOS, it's reversed—the lower the value, the darker it gets. To make it consistent, we should modify iOS to use 1 - dimmedAlpha.

Also, on iOS, the dimming animation starts after the sheet is fully opened, which feels unnatural. Moving it to viewWillAppear would make it start while the sheet is opening, which looks more natural.

Here’s the updated code with these fixes.

func viewControllerWillAppear() {
  // Only apply dimming if the sheet has dimmed property set to true
  if viewController.dimmed {
    let opacity = 1 - dimmedAlpha;
    // Add this sheet's opacity to the stack and dim root view controller
    TrueSheetView.sheetOpacityStack.append(opacity)
    UIView.animate(withDuration: 0.3) {
      if let rootViewController = UIApplication.shared.windows.first?.rootViewController {
        rootViewController.view.alpha = opacity
      }
    }
  }

  guard let contentView, let scrollView, let containerView else {
    return
  }

  // Add constraints to fix weirdness and support ScrollView
  contentView.pinTo(view: containerView, constraints: nil)
  scrollView.pinTo(view: contentView, constraints: nil)
}

func viewControllerDidAppear() {
}

@camchis
Copy link
Author

camchis commented Mar 27, 2025

Thanks @crux153!!
Both very good points

I've pushed a change to add the dimming logic inside viewControllerWillAppear and have removed viewControllerDidAppear

Have also made the dimmedAlpha behaviour consistent with Android, good catch :)

@crux153
Copy link

crux153 commented Mar 28, 2025

@camchis Great work!

And for Android implementation, using the built-in setDimAmount method seems simpler than using a custom view.
You can just add one line setDimAmount(dimmedAlpha) to the setupDimmedBackground method in TrueSheetDialog.kt

/**
 * Setup dimmed sheet.
 * `dimmedIndex` will further customize the dimming behavior.
 */
fun setupDimmedBackground(sizeIndex: Int) {
  window?.apply {
    val view = findViewById<View>(com.google.android.material.R.id.touch_outside)

    if (dimmed && sizeIndex >= dimmedIndex) {
      // Remove touch listener
      view.setOnTouchListener(null)

      // Add the dimmed background
      setFlags(
        WindowManager.LayoutParams.FLAG_DIM_BEHIND,
        WindowManager.LayoutParams.FLAG_DIM_BEHIND
      )

      setDimAmount(dimmedAlpha)

      setCanceledOnTouchOutside(dismissible)
    } else {
      // Override the background touch and pass it to the components outside
      view.setOnTouchListener { v, event ->
        event.setLocation(event.rawX - v.x, event.rawY - v.y)
        reactContext.currentActivity?.dispatchTouchEvent(event)
        false
      }

      // Remove the dimmed background
      clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)

      setCanceledOnTouchOutside(false)
    }
  }
}

@camchis
Copy link
Author

camchis commented Mar 28, 2025

@crux153 thanks, I 100% agree that the setDimAmount method is a lot simpler than using a custom view, however I can't seem to get it working at all when I implement it, I'm struggling to figure out why which is why I went with a custom view in the end

@crux153
Copy link

crux153 commented Mar 28, 2025

@camchis Here's the patch that I'm currently using.

diff --git a/android/src/main/java/com/lodev09/truesheet/TrueSheetDialog.kt b/android/src/main/java/com/lodev09/truesheet/TrueSheetDialog.kt
index f4b38fc94de83678124a86bc3c7ab3e855e585b0..fddd0d46fb673669a093ba0b2faf27825391e761 100644
--- a/android/src/main/java/com/lodev09/truesheet/TrueSheetDialog.kt
+++ b/android/src/main/java/com/lodev09/truesheet/TrueSheetDialog.kt
@@ -46,6 +46,13 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
    */
   var dimmedIndex = 0
 
+  /**
+   * The alpha value of the dimmed background.
+   *
+   * @default 0.75f
+   */
+  var dimmedAlpha = 0.75f
+
   /**
    * The maximum window height
    */
@@ -156,6 +163,8 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
           WindowManager.LayoutParams.FLAG_DIM_BEHIND
         )
 
+        setDimAmount(dimmedAlpha)
+
         setCanceledOnTouchOutside(dismissible)
       } else {
         // Override the background touch and pass it to the components outside
diff --git a/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt b/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt
index e946d96815bb49cb6f17a71587ed2fc4925e0625..9fd80c68ac7cc970d4cb4bb4d13bbd0e738cbbba 100644
--- a/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt
+++ b/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt
@@ -362,6 +362,12 @@ class TrueSheetView(context: Context) :
     }
   }
 
+  fun setDimmedAlpha(alpha: Float) {
+    if (sheetDialog.dimmedAlpha == alpha) return
+
+    sheetDialog.dimmedAlpha = alpha
+  }
+
   fun setDimmedIndex(index: Int) {
     if (sheetDialog.dimmedIndex == index) return
 
diff --git a/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt b/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt
index 0ed9b8a0e69cc529d421e34ef937186dfe7e72d0..edecc9570fb2a15d336212f9d49f02674043dcca 100644
--- a/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt
+++ b/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt
@@ -67,6 +67,11 @@ class TrueSheetViewManager : ViewGroupManager<TrueSheetView>() {
     view.setDimmed(dimmed)
   }
 
+  @ReactProp(name = "dimmedAlpha")
+  fun setDimmedAlpha(view: TrueSheetView, alpha: Float) {
+    view.setDimmedAlpha(alpha)
+  }
+
   @ReactProp(name = "initialIndex")
   fun setInitialIndex(view: TrueSheetView, index: Int) {
     view.initialIndex = index

@coder966 coder966 mentioned this pull request Apr 4, 2025
@andrew-stupchuk
Copy link

andrew-stupchuk commented Apr 7, 2025

Hey @lodev09. Could you please take a look at the grabber in the attached video? When it opens, it initially appears black, then quickly turns grey. Also, both bottom corners briefly flash white. I was wondering if there might be a workaround or fix for this? This issue is consistently reproducible when using the light theme. In the attached video, the corners appear to be cut off when switching to the second sheet

@lxup
Copy link

lxup commented Apr 12, 2025

Really excited to get the stacked sheet, it's the only thing I'm missing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants